﻿/*代码说明
 * Session["IAMGuid"]用于iam请求的guid验证
 * Session["IAMGuid"]包含一个arraylist
 */
using System;
using System.Text;
using IAM.Interface.Common.XMLResolution;
using IAM.Interface.Common.Encrypt;
using IAM.Interface.Common.Providers;
using IAM.Interface.Model.Interface;
using System.Xml;
using IAM.Interface.Model.ENUM;
using IAM.Interface.Common.Abnormity;
using IAM.Interface.Model;
using System.Web;

namespace IAM.Interface.Common.Context
{
    /// <summary>
    /// 响应端发送消息上下文控制
    /// </summary>
    public class ResponseContextControl
    {
        #region 构造函数
        public ResponseContextControl()
        { }
        public ResponseContextControl(ResponseContextModel contextmodel)
        {
            this._contextmodel = contextmodel;
        }

        #endregion
        #region 属性
        private ResponseContextModel _contextmodel = null;
        private string _xml = "";
        private Request _request = null;
        private ResponseException _re = null;

        /// <summary>
        /// 传送控制类实体对象
        /// </summary>
        public ResponseContextModel ContextModel
        {
            get
            {
                return _contextmodel;
            }
            set
            {
                _contextmodel = value;
            }
        }
        public string XML
        {
            get
            {
                return _xml;
            }
            set
            {
                _xml = value;
            }

        }
        /// <summary>
        /// xml请求包
        /// </summary>
        public Request Request
        {
            get
            {
                return _request;
            }
            set
            {
                _request = value;
            }
        }
        /// <summary>
        /// 异常消息
        /// </summary>
        public ResponseException ResponseException
        {
            get
            {
                return _re;
            }
            set
            {
                _re = value;
            }

        }
        #endregion
        #region 接收消息
        /// <summary>
        /// 接收消息
        /// 1.解密
        /// 2.解析包
        /// 3.根据操作类型返回对象
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        private object Incept()
        {
            //1.解密
            EncryptDecrypt endecrypt = new EncryptDecrypt();
            endecrypt.Key = ContextModel.Key;
            XML = endecrypt.Decrypt(ContextModel.XML);
            //1.1 验证签名 
            bool vs = true;

            vs = ValidateSign(XML);
            if (!vs)
            {
                throw (new IAM.Interface.Common.Abnormity.ResponseException(700));
            }
            XmlDocument _xmldocumenttemp = new XmlDocument();
            _xmldocumenttemp.LoadXml(XML);
            //1.2 验证请求时间和当前服务器时间的间隔是否超过了5分钟
            bool isovertime = ValidateOvertime(System.Convert.ToDateTime(_xmldocumenttemp.DocumentElement.Attributes["RequestTime"].Value));
            if (!isovertime)
            {
                throw (new IAM.Interface.Common.Abnormity.ResponseException(710));
            }

            //1.3 验证最近访问的Session 的GUID是否重复
            bool _validateguid = ValidateGuid(_xmldocumenttemp.DocumentElement.Attributes["TransactionID"].Value);
           if (!_validateguid)
           {
               throw (new IAM.Interface.Common.Abnormity.ResponseException(800));
           }
            //2.解析包
            Request request = new Request();
            request.XmlDocument = new XmlDocument();
            request.XmlInfo = XML;
            request.XmlDocument.LoadXml(request.XmlInfo);
            Request = request;
            //3.根据操作类型返回对象
            XmlObjConversion xoc = new XmlObjConversion(request.GetActionType(), request.XmlDocument.DocumentElement.Name);
            xoc.CurrentXmlNode = request.GetCurrentNode();
            return xoc.ConvertToObj();
        }
        #endregion
        #region 发送消息
        /// <summary>
        /// 发送消息
        /// 1.将对象转换成为xml
        /// 2.拼完整包请求包
        /// 3.对信息加密
        /// </summary>
        /// <param name="obj">返回的实体对象</param>
        /// <param name="request">xml请求包</param>
        /// <param name="exception">异常消息</param>
        /// <returns></returns>
        private string Send(
            IConvertXml obj,
            Request request,
            ResponseException exception)
        {
            string xml = "";
            //1.将对象转换成为xml
            XmlObjConversion xoc = new XmlObjConversion(obj);
            xml = xoc.GetXml();
            //2.拼完整包请求包
            AbstractXMLResolution abxmlresolution = new Response(
                request.GetActionType(),
                exception,
                request.GetTransactionID());
            abxmlresolution.XmlInfo = xml;
            xml = abxmlresolution.GetWholeXML();
            //3.对信息加密
            EncryptDecrypt endecrypt = new EncryptDecrypt();
            endecrypt.Key = ContextModel.Key;
            xml = endecrypt.Encrypt(xml);
            return xml;
        }
        #endregion
        #region 调用本地处理方法
        /// <summary>
        /// 调用本地处理方法
        /// </summary>
        /// <param name="obj">参数对象</param>
        /// <param name="request">xml请求包</param>
        /// <returns></returns>
        private object TransferBLL(object obj, Request request)
        {
            System.Object returnobj = null;

            IAM.Interface.DAL.Response.IdentityMgnt businessIM = null;
            IAM.Interface.DAL.Response.ACIMgnt businessACIMgnt = null;
            IAM.Interface.DAL.Response.DelegationMgnt busnessDM = null;
            IAM.Interface.DAL.Response.OrganizationMgnt busnessOM = null;
            try
            {
                ResponseException = new ResponseException();
                switch (request.GetActionType())
                {
                    case ActionType.IDEN_MANAGE://身份信息管理
                        businessIM = new IAM.Interface.DAL.Response.IdentityMgnt();
                        switch (request.GetOperationType())
                        {
                            case OperationType.Create:
                                returnobj = businessIM.CreateIdentity((Identity)obj);
                                break;
                            case OperationType.Enable:
                                returnobj = businessIM.EnableIdentity((Identity)obj);
                                break;
                            case OperationType.Disable:
                                returnobj = businessIM.DisableIdentity((Identity)obj);
                                break;
                            case OperationType.Delete:
                                returnobj = businessIM.DeleteIdentity((Identity)obj);
                                break;
                            case OperationType.Update:
                                returnobj = businessIM.UpdateIdentity((Identity)obj);
                                break;
                        }
                        break;
                    case ActionType.IDEN_GETACMODEL://获取权限模型
                        businessACIMgnt = new IAM.Interface.DAL.Response.ACIMgnt();
                        returnobj = businessACIMgnt.GetACIModel();
                        break;
                    case ActionType.IDEN_GETUSERACI://获取用户权限信息
                        businessACIMgnt = new IAM.Interface.DAL.Response.ACIMgnt();
                        returnobj = businessACIMgnt.GetUserACI((AccountInfo)obj);
                        break;
                    case ActionType.IDEN_SETUSERACI://设置用户权限信息
                        businessACIMgnt = new IAM.Interface.DAL.Response.ACIMgnt();
                        returnobj = businessACIMgnt.SetUserACI((ACI)obj);
                        break;
                    case ActionType.ORG_UPDATE://组织信息更新
                        busnessOM = new IAM.Interface.DAL.Response.OrganizationMgnt();
                        returnobj = busnessOM.UpdateOrganize((OrganizeInfo)obj);
                        if ((bool)returnobj == false)//
                        {
                            returnobj = new NullityObj();

                        }
                        else
                        {
                            returnobj = new NullityObj();
                        }
                        break;
                    case ActionType.ORG_CREATE://组织机构创立
                        busnessOM = new IAM.Interface.DAL.Response.OrganizationMgnt();
                        returnobj = busnessOM.CreateOrganize((OrganizeInfo)obj);
                        if ((bool)returnobj == false)//
                        {
                            returnobj = new NullityObj();

                        }
                        else
                        {
                            returnobj = new NullityObj();
                        }
                        break;
                    case ActionType.ORG_DELETE://组织结构删除（包括合并）
                        busnessOM = new IAM.Interface.DAL.Response.OrganizationMgnt();
                        returnobj = busnessOM.DeleteOrganize((OrganizeDeleteParameter)obj);
                        if ((bool)returnobj == false)//
                        {
                            returnobj = new NullityObj();

                        }
                        else
                        {
                            returnobj = new NullityObj();
                        }
                        break;
                    case ActionType.DM_GETMODULELIST://获取可代理模块列表
                        busnessDM = new IAM.Interface.DAL.Response.DelegationMgnt();
                        returnobj = busnessDM.GetModuleList();
                        break;
                    case ActionType.DM_GETDELEINFO://获取用户代理信息
                        busnessDM = new IAM.Interface.DAL.Response.DelegationMgnt();
                        returnobj = busnessDM.GetDelegationInfo((AccountInfo)obj);
                        break;
                    case ActionType.DM_SETDELEINFO://设置用户代理信息
                        busnessDM = new IAM.Interface.DAL.Response.DelegationMgnt();
                        returnobj = busnessDM.SetDelegationInfo((AIDelegations)obj);
                        break;
                    //case "IDEN_USERLIST"://获取用户信息列表
                    //    xn = (XmlNode)xe;
                    //    break;
                    //case "AUDIT_FETCH"://获取审计信息
                    //    xn = xe.SelectSingleNode("Logs");
                    //    break;
                }
            }
            catch (ResponseException re)
            {

                ResponseException = re;
                return new NullityObj();
            }
            catch (Exception ex)
            {
                ResponseException.SetStateMessage(500, ex.Message);
                return new NullityObj();
            }
            return returnobj;
        }
        #endregion
        #region 响应端上下文控制
        /// <summary>
        /// 响应端上下文控制<br/>
        /// 1.接收消息<br/>
        /// 2.调用本地处理方法<br/>
        /// 3.发送消息
        /// </summary>
        /// <returns></returns>
        public string ContextControl()
        {
            //1.接收消息
            object inceptobj = null;
            try
            {
                inceptobj = Incept();
            }
            catch (ResponseException re)
            {
                ResponseException = re;
                return Send((IConvertXml)new NullityObj(), new Request(), this.ResponseException);
            }
            catch (Exception ex)
            {
                ResponseException = new ResponseException();
                ResponseException.SetStateMessage(500, ex.Message);
                return Send((IConvertXml)new NullityObj(), new Request(), this.ResponseException);
            }
            //2.调用本地处理方法
            object resultobj = TransferBLL(inceptobj, this.Request);
            //3.发送消息
            return Send((IConvertXml)resultobj, this.Request, this.ResponseException);
        }
        #endregion

        #region 判断请求方是否是可信任的IP地址
        /// <summary>
        /// 判断请求方是否是可信任的IP地址
        /// </summary>
        /// <returns></returns>
        public bool ValidateRequestIP()
        {
            #region 服务器环境变量名 注销
            //requesttip.Append("ALL_HTTP:" + HttpContext.Current.Request.ServerVariables["ALL_HTTP"] + "\n\r");
            //requesttip.Append("ALL_RAW:" + HttpContext.Current.Request.ServerVariables["ALL_RAW"] + "\n\r");
            //requesttip.Append("APPL_MD_PATH:" + HttpContext.Current.Request.ServerVariables["APPL_MD_PATH"] + "\n\r");
            //requesttip.Append("APPL_PHYSICAL_PATH:" + HttpContext.Current.Request.ServerVariables["APPL_PHYSICAL_PATH"] + "\n\r");
            //requesttip.Append("AUTH_PASSWORD:" + HttpContext.Current.Request.ServerVariables["AUTH_PASSWORD"] + "\n\r");
            //requesttip.Append("AUTH_TYPE:" + HttpContext.Current.Request.ServerVariables["AUTH_TYPE"] + "\n\r");
            //requesttip.Append("AUTH_USER:" + HttpContext.Current.Request.ServerVariables["AUTH_USER"] + "\n\r");
            //requesttip.Append("CERT_COOKIE:" + HttpContext.Current.Request.ServerVariables["CERT_COOKIE"] + "\n\r");
            //requesttip.Append("CERT_FLAGS:" + HttpContext.Current.Request.ServerVariables["CERT_FLAGS"] + "\n\r");
            //requesttip.Append("CERT_ISSUER:" + HttpContext.Current.Request.ServerVariables["CERT_ISSUER"] + "\n\r");
            //requesttip.Append("CERT_KEYSIZE:" + HttpContext.Current.Request.ServerVariables["CERT_KEYSIZE"] + "\n\r");
            //requesttip.Append("CERT_SECRETKEYSIZE:" + HttpContext.Current.Request.ServerVariables["CERT_SECRETKEYSIZE"] + "\n\r");
            //requesttip.Append("CERT_SERIALNUMBER:" + HttpContext.Current.Request.ServerVariables["CERT_SERIALNUMBER"] + "\n\r");
            //requesttip.Append("CERT_SERVER_ISSUER:" + HttpContext.Current.Request.ServerVariables["CERT_SERVER_ISSUER"] + "\n\r");
            //requesttip.Append("CERT_SERVER_SUBJECT:" + HttpContext.Current.Request.ServerVariables["CERT_SERVER_SUBJECT"] + "\n\r");
            //requesttip.Append("CERT_SUBJECT:" + HttpContext.Current.Request.ServerVariables["CERT_SUBJECT"] + "\n\r");
            //requesttip.Append("CONTENT_LENGTH:" + HttpContext.Current.Request.ServerVariables["CONTENT_LENGTH"] + "\n\r");
            //requesttip.Append("CONTENT_TYPE:" + HttpContext.Current.Request.ServerVariables["CONTENT_TYPE"] + "\n\r");
            //requesttip.Append("GATEWAY_INTERFACE:" + HttpContext.Current.Request.ServerVariables["GATEWAY_INTERFACE"] + "\n\r");
            //requesttip.Append("HTTPS:" + HttpContext.Current.Request.ServerVariables["HTTPS"] + "\n\r");
            //requesttip.Append("HTTPS_KEYSIZE:" + HttpContext.Current.Request.ServerVariables["HTTPS_KEYSIZE"] + "\n\r");
            //requesttip.Append("HTTPS_SECRETKEYSIZE:" + HttpContext.Current.Request.ServerVariables["HTTPS_SECRETKEYSIZE"] + "\n\r");
            //requesttip.Append("HTTPS_SERVER_ISSUER:" + HttpContext.Current.Request.ServerVariables["HTTPS_SERVER_ISSUER"] + "\n\r");
            //requesttip.Append("HTTPS_SERVER_SUBJECT:" + HttpContext.Current.Request.ServerVariables["HTTPS_SERVER_SUBJECT"] + "\n\r");
            //requesttip.Append("INSTANCE_ID:" + HttpContext.Current.Request.ServerVariables["INSTANCE_ID"] + "\n\r");
            //requesttip.Append("INSTANCE_META_PATH:" + HttpContext.Current.Request.ServerVariables["INSTANCE_META_PATH"] + "\n\r");
            //requesttip.Append("LOCAL_ADDR:" + HttpContext.Current.Request.ServerVariables["LOCAL_ADDR"] + "\n\r");
            //requesttip.Append("LOGON_USER:" + HttpContext.Current.Request.ServerVariables["LOGON_USER"] + "\n\r");
            //requesttip.Append("PATH_INFO:" + HttpContext.Current.Request.ServerVariables["PATH_INFO"] + "\n\r");
            //requesttip.Append("PATH_TRANSLATED:" + HttpContext.Current.Request.ServerVariables["PATH_TRANSLATED"] + "\n\r");
            //requesttip.Append("QUERY_STRING:" + HttpContext.Current.Request.ServerVariables["QUERY_STRING"] + "\n\r");
            //requesttip.Append("REMOTE_ADDR:" + HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"] + "\n\r");
            //requesttip.Append("REMOTE_HOST:" + HttpContext.Current.Request.ServerVariables["REMOTE_HOST"] + "\n\r");
            //requesttip.Append("REMOTE_USER:" + HttpContext.Current.Request.ServerVariables["REMOTE_USER"] + "\n\r");
            //requesttip.Append("REQUEST_METHOD:" + HttpContext.Current.Request.ServerVariables["REQUEST_METHOD"] + "\n\r");
            //requesttip.Append("SCRIPT_NAME:" + HttpContext.Current.Request.ServerVariables["SCRIPT_NAME"] + "\n\r");
            //requesttip.Append("SERVER_NAME:" + HttpContext.Current.Request.ServerVariables["SERVER_NAME"] + "\n\r");
            //requesttip.Append("SERVER_PORT:" + HttpContext.Current.Request.ServerVariables["SERVER_PORT"] + "\n\r");
            //requesttip.Append("SERVER_PORT_SECURE:" + HttpContext.Current.Request.ServerVariables["SERVER_PORT_SECURE"] + "\n\r");
            //requesttip.Append("SERVER_PROTOCOL:" + HttpContext.Current.Request.ServerVariables["SERVER_PROTOCOL"] + "\n\r");
            //requesttip.Append("SERVER_SOFTWARE:" + HttpContext.Current.Request.ServerVariables["SERVER_SOFTWARE"] + "\n\r");
            //requesttip.Append("URL:" + HttpContext.Current.Request.ServerVariables["URL"] + "\n\r");
            #endregion
            //发出请求的ip
            string requesttip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"].ToString();
            //本地配置的安全访问ip
            string directory = System.AppDomain.CurrentDomain.BaseDirectory;
            if (directory.Substring(directory.Length - 1) == "/" || directory.Substring(directory.Length - 1) == "\\")
            {
            }
            else
            {
                directory = directory + "\\";
            }
            string appsfilename = directory + "RequestIPs.xml";

            XmlDocument xd = new XmlDocument();
            xd.Load(appsfilename);

            //获取所有的RequestIP节点
            XmlNodeList xnl = xd.SelectNodes("//RequestIP");
            bool reslut = false;
            foreach (XmlNode xnoneofips in xnl)
            {
                if (xnoneofips.InnerText.ToLower().Trim() == requesttip.ToLower().Trim())
                {
                    reslut = true;
                    break;
                }
            }
            return reslut;
        }
        #endregion

        #region 判断xml签名是否一致
        /// <summary>
        /// 判断xml签名是否一致
        /// </summary>
        /// <param name="xml">解码后的xml请求包</param>
        /// <returns></returns>
        public bool ValidateSign(string xml)
        {
            // 计算XML的摘要
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xml);
            XMlSign xs = new XMlSign();

            string signatureValue = xs.SignXml(xmlDoc);

            //对signatureValue 进行加密后比较
            EncryptDecrypt endecrypt = new EncryptDecrypt();
            endecrypt.Key = ContextModel.Key;
            signatureValue = endecrypt.Encrypt(signatureValue);

            if (signatureValue.Trim() == ContextModel.Sign.Trim())
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 获取本地配置密钥
        /// <summary>
        /// 获取本地配置密钥
        /// </summary>
        /// <returns></returns>
        public static string GetConfigKey()
        {
            //一获取加密的key
            string key = System.Configuration.ConfigurationSettings.AppSettings["IAM_Key"];

            //对密钥进行解密
            EncryptDecrypt ed = new EncryptDecrypt();
            ed.Key = ed.GenerateKey();
            string result = ed.Decrypt(key);
            return result;
        }
        #endregion

        #region 验证请求时间和当前服务器时间的间隔是否超过了5分钟
        /// <summary>
        /// 验证请求时间和当前服务器时间的间隔是否超过了5分钟
        /// </summary>
        /// <param name="requesttime"></param>
        /// <returns></returns>
        private bool ValidateOvertime(DateTime requesttime)
        {
            DateTime currenttime = System.DateTime.Now;
            System.TimeSpan ts = currenttime.Subtract(requesttime);
            double timemargin = System.Math.Abs(ts.TotalMinutes);
            if (timemargin > 5.0)
            {
                return false;
            }
            return true;
        }
        #endregion

        #region 验证最近访问的Application 的GUID是否重复
        private bool ValidateGuid(string requestguid)
        {
            bool result = true;
           
            //System.Collections.ArrayList arr = null;
            //if (System.Web.HttpContext.Current.Session["IAMGuid"] != null)
            //{
            //    arr = (System.Collections.ArrayList)System.Web.HttpContext.Current.Application["IAMGuid"];

            //    foreach (object _obj in arr)
            //    {
            //        string str = _obj.ToString();
            //        if (str == requestguid)
            //        {
            //            result = false;
            //        }
            //    }
            //    if (result == true)
            //    {
            //        if (arr.Count > 4)
            //        {
            //            arr.RemoveAt(arr.Count - 1);
            //            arr.Insert(0, requestguid);
            //        }
            //        else
            //        {
            //            arr.Insert(0, requestguid);
            //        }
            //        System.Web.HttpContext.Current.Application["IAMGuid"] = arr;
                    
            //    }
            //}
            //else
            //{
            //    arr = new System.Collections.ArrayList();
            //    arr.Add(requestguid);
            //    System.Web.HttpContext.Current.Application["IAMGuid"] = arr;
            //    result = true;
            //}


            return result;
        }
        #endregion
    }
}
